package dbinfo

import (
	"crypto/md5"
	"encoding/hex"
	"errors"
	"fmt"
	"os"
	"path/filepath"
	"reflect"
	"strings"
	"sync"
	"time"
	"unicode/utf8"

	"github.com/shopspring/decimal"
	"gopkg.in/ini.v1"
)

//const timeFormat = "2006-01-02 15:04:05"

var (
	entityWriteLock sync.Mutex                //保存锁
	entityMap       = make(map[string]Entity) //注册实体结构体集合
	// dbMap           = make(map[string]string) //注册数据库别名集合
	// tableNameMap    = make(map[string]string) //实体的TableName缓存,TableName用于在进行gorm查询时自定义表名需要

	// --  数据库字段名常量 -- //
	tableKeyNameMap          = map[string]string{}
	BaseSystemName           string //基本数据库库名
	TableMajorKeyString      string //数据库表主键名称(字符串形式)
	TableMajorKeyAutoInt     string //数据库表主键名称(自增长形式)
	TableMajorKeyUuId        string //数据库表主键名称(UUID形式)
	TablePidKey              string //数据库表字段名称-上级字段名
	TablePathKey             string //数据库表字段名称-主键路径名
	TableTreeNodeName        string //数据库表字段名称-树形节点名
	TableCreatorName         string //数据库表字段名称-创建人
	TableCreateDateName      string //数据库表字段名称-创建时间
	TableModifiederName      string //数据库表字段名称-修改人
	TableModifiedDateName    string //数据库表字段名称-修改时间
	TableStateName           string //数据库表字段名称-状态值
	TableIndexName           string //数据库表字段名称-排序值
	TableVersionName         string //数据库表字段名称-版本号
	TablePasswordName        string //数据库表字段名称-密码
	TableDelSignName         string //数据库表字段名称-逻辑删除标识
	TableSetpName            string //数据库表字段名称-步骤值
	TableOnlyignName         string //数据库表字段名称-唯一标识
	TableNameDictionary      string //字典表表名
	TableDictionaryValueName string //字典表值字段名
	TableRecordKeyName       string //记录验证串字段名
	TablesSign               string //标识字段名
	TablesMemo               string //备注字段名

	TableTreeRootValue = "00" //数据库树型表根节点默认值
)

// 实体接口定义,用于规范实体结构体
type Entity interface {
	New() Entity                       //创建结构实体
	BaseColumnNames() string           //结构体映射表的字段名串
	BaseEntity() Entity                //取基础实体,用于在子类(嵌套结构体)时同样获得基类
	GetDataInfo(name string) *DataInfo //取数据结构信息
	TableName() string                 //结构体映射表名,当gorm进行查询时要明确与gorm规则不同的表名时使用
	OwnerName() string                 //结构体映射库名,去除'Dev_'等前缀
	OwnerTable() string                //结构体映射表名,无库名
}

func init() {
	initTableKeyName()
}

// --------- 注册实体结构体集合 开始 ---------//

/**
 * 注册实体结构体
 * @param name
 * @param entity
 */
func RegisterEntity(name string, entity Entity) Entity {
	entityWriteLock.Lock()         //加锁
	defer entityWriteLock.Unlock() //解锁

	entityMap[name] = entity

	return entity
}

/**
 * 取实体结构体
 * @param name
 * @return
 */
func GetEntity(name string) Entity {
	entityWriteLock.Lock()         //加锁
	defer entityWriteLock.Unlock() //解锁

	return entityMap[name]
}

// --------- 注册实体结构体集合 结束 ---------//

// --------- 注册数据库别名集合 开始 ---------//

// /**
//  * 注册数据库别名
//  * @param name
//  * @param entity
//  */
// func RegisterDbName(id, name string) string {
// 	if id == "" {
// 		return ""
// 	}

// 	if name == "" {
// 		return ""
// 	}

// 	entityWriteLock.Lock()         //加锁
// 	defer entityWriteLock.Unlock() //解锁

// 	dbMap[id] = name
// 	return name
// }

// /**
//  * 取数据库别名
//  * @param id
//  * @return
//  */
// func GetDbNameById(id string) string {
// 	if id == "" {
// 		return ""
// 	}

// 	entityWriteLock.Lock()         //加锁
// 	defer entityWriteLock.Unlock() //解锁

// 	return dbMap[id]
// }

// /**
//  * 取数据库别名
//  * @param entity
//  * @return
//  */
// func GetDbName(entity Entity) string {
// 	if entity == nil {
// 		return ""
// 	}

// 	entityWriteLock.Lock()         //加锁
// 	defer entityWriteLock.Unlock() //解锁

// 	id := EntityDbName(entity)
// 	return dbMap[id]
// }

// --------- 注册数据库别名集合 结束 ---------//

// --------- 注册实体结构体对应数据库表名集合 开始 ---------//

// /**
//  * 注册实体表名
//  * @param id
//  * @param name
//  */
// func RegisterTableName(id, name string) string {
// 	if id == "" {
// 		return ""
// 	}

// 	if name == "" {
// 		return ""
// 	}

// 	entityWriteLock.Lock()         //加锁
// 	defer entityWriteLock.Unlock() //解锁

// 	tableNameMap[id] = name

// 	return name
// }

// /**
//  * 取实体表名
//  * @param id
//  * @return
//  */
// func GetTableNameById(id string) string {
// 	if id == "" {
// 		return ""
// 	}

// 	entityWriteLock.Lock()         //加锁
// 	defer entityWriteLock.Unlock() //解锁

// 	if name, ok := tableNameMap[id]; ok {
// 		return name
// 	}

// 	return ""
// }

// /**
//  * 取实体表名
//  * @param entity
//  * @return
//  */
// func GetTableName(entity Entity) string {
// 	if entity == nil {
// 		return ""
// 	}

// 	entityWriteLock.Lock()         //加锁
// 	defer entityWriteLock.Unlock() //解锁

// 	id := EntityTableName(entity)
// 	if name, ok := tableNameMap[id]; ok {
// 		return name
// 	}

// 	return ""
// }

// --------- 注册实体结构体对应数据库表名集合 结束 ---------//

/**
 * 取基础实体,用于在子类(嵌套结构体)时同样获得基类
 * @param entity
 * @return
 */
func BaseEntity(entity Entity) Entity {
	return entity.BaseEntity() //调用子类的实现方法
}

/**
 * 按名称取数据结构信息
 * @param entity
 * @param name
 * @return
 */
func GetDataInfo(entity Entity, name string) *DataInfo {
	return entity.GetDataInfo(name) //子类实现
}

/**
 * 按字段顺序取数据结构信息
 * @param entity
 * @param name
 * @return
 */
func GetDataInfoByIndex(entity Entity, index int) *DataInfo {
	if index < 0 {
		index = 0
	}

	array := strings.Split(entity.BaseColumnNames(), ",")
	if len(array) <= index {
		return nil
	}

	return entity.GetDataInfo(array[index]) //子类实现
}

/**
 * 判断是否存在字段名
 * @param entity
 * @param name
 * @return
 */
func HasColumnName(entity Entity, name string) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, v := range array {
		if v == name {
			return true
		}
	}

	return false
}

/**
 * 取所有数据结构信息
 * @param entity
 * @return
 */
func AllDataInfo(entity Entity) []*DataInfo {
	array := strings.Split(entity.BaseColumnNames(), ",")

	result := []*DataInfo{}
	for _, key := range array {
		result = append(result, entity.GetDataInfo(key))
	}

	return result
}

/**
 * 结构体映射表的字段名集合
 * @param entity
 * @return
 */
func BaseColumnNameList(entity Entity) []string {
	return strings.Split(entity.BaseColumnNames(), ",")
}

/**
 * 创建指定长度的结构实体集合
 * @param entity
 * @param iSize
 * @return
 */
func NewList(entity Entity, iSize int) []Entity {
	result := make([]Entity, iSize)
	for i := 0; i < iSize; i++ {
		result[i] = entity.New()
	}

	return result
}

/**
 * 设置默认值
 * @param entity
 * @param cover 是否覆盖
 */
func SetDefault(entity Entity, cover bool) {
	array := strings.Split(entity.BaseColumnNames(), ",") //结构体映射表的字段名串
	data := make(map[string]interface{})
	for _, name := range array {
		dataInfo := entity.GetDataInfo(name)
		if dataInfo.GoDefaultData == nil {
			continue
		}

		data[name] = dataInfo.GoDefaultData
	}

	pValue := reflect.ValueOf(entity) // 获取指针指向的值

	setFieldsVal(pValue, data, cover)
}

/**
 * 取主键数据结构信息
 * @param entity
 * @return
 */
func GetKeyDataInfo(entity Entity) []*DataInfo {
	array := strings.Split(entity.BaseColumnNames(), ",")

	result := []*DataInfo{}
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.Gbkey {
			result = append(result, dataInfo)
		}
	}

	return result
}

/**
 * 取所属数据库名
 * @param entity
 * @return
 */
func EntityDbName(entity Entity) string {
	array := strings.Split(entity.BaseColumnNames(), ",")

	var dataInfo *DataInfo
	for _, key := range array {
		dataInfo = entity.GetDataInfo(key)
		if dataInfo.Gbkey {
			return dataInfo.GsDbName
		}
	}

	if dataInfo == nil {
		return ""
	}

	return dataInfo.GsDbName
}

/**
 * 取所属数据库表名
 * @param entity
 * @return
 */
func EntityTableName(entity Entity) string {
	array := strings.Split(entity.BaseColumnNames(), ",")

	var dataInfo *DataInfo
	for _, key := range array {
		dataInfo = entity.GetDataInfo(key)
		if dataInfo.Gbkey {
			return dataInfo.GsTableName
		}
	}

	if dataInfo == nil {
		return ""
	}

	return dataInfo.GsDbName
}

/**
 * 取所属数据库表主键名
 * 注意:如果有多个主键,则取第一个主键
 * @param entity
 * @return
 */
func EntityKeyName(entity Entity) string {
	array := strings.Split(entity.BaseColumnNames(), ",")

	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.Gbkey {
			return dataInfo.GsName
		}
	}

	return ""
}

/**
 * 取所属数据库表主键名
 * 注意:如果有多个主键,则全取,并以','分隔
 * @param entity
 * @return
 */
func EntityKeyNames(entity Entity) string {
	array := strings.Split(entity.BaseColumnNames(), ",")

	result := ""
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.Gbkey {
			result += "," + dataInfo.GsName
		}
	}

	return strings.TrimPrefix(result, ",") //去掉前缀
}

/**
 * 取所属数据库表主键长度
 * 注意:如果有多个主键,则取第一个主键
 * @param entity
 * @return
 */
func EntityKeyLength(entity Entity) int {
	array := strings.Split(entity.BaseColumnNames(), ",")

	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.Gbkey {
			return dataInfo.GiMaxLength
		}
	}

	return 8
}

/**
 * 取所属数据库表主键长度
 * 注意:如果有多个主键,则全取
 * @param entity
 * @return
 */
func EntityKeysLength(entity Entity) map[string]int {
	array := strings.Split(entity.BaseColumnNames(), ",")

	result := make(map[string]int, 0)
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.Gbkey {
			result[dataInfo.GsName] = dataInfo.GiMaxLength
		}
	}

	return result
}

// ---------- 去除字符类型属性前后空格 开始 -------- //

/**
 * 去除字符类型属性前后空格
 */
func TrimFields(entity Entity) {
	v := reflect.ValueOf(entity).Elem()

	trimStringFields(v) // 调用函数清除字符串字段的前后空格
}

/**
 * 通用函数，用于递归处理结构体及其匿名字段中的字符串
 * @param v 结构体或匿名结构体
 */
func trimStringFields(v reflect.Value) {
	for i := 0; i < v.NumField(); i++ {
		field := v.Field(i)
		fieldType := v.Type().Field(i)

		// 检查字段是否为匿名结构体
		if fieldType.Anonymous {
			trimStringFields(field)
			continue
		}

		if field.Kind() == reflect.String {
			field.SetString(strings.TrimSpace(field.String())) // 清除前后空格
			continue
		}

		if field.Kind() == reflect.Struct {
			trimStringFields(field) // 如果字段是结构体，则递归调用trimStringFields
			continue
		}
	}
}

// ---------- 去除字符类型属性前后空格 结束 -------- //

/*
 * 创建记录验证值
 * @param entity
 * @return
 */
func CreateRecordKey(entity Entity) string {
	pValue := reflect.ValueOf(entity) // 获取指针指向的值

	array := strings.Split(entity.BaseColumnNames(), ",")
	valMap := getFieldsVal(pValue) // 递归遍历结构体的所有字段

	temp := ""
	for _, k := range array { //只有数组才能固定顺序
		if k == "sRecordKey" { //sRecordKey字段不能参与,并且一旦轮询到sRecordKey就结束
			break
		}

		v, ok := valMap[k]
		if !ok {
			continue
		}

		if v == nil {
			temp = temp + ";"
			continue
		}

		switch reflect.TypeOf(v).String() {
		case "time.Time":
			temp = temp + v.(time.Time).Format(timeFormat) + ";"
		default:
			temp = temp + fmt.Sprintf("%v", v) + ";"
		}
	}

	data := []byte(temp)
	md5Ctx := md5.New()
	md5Ctx.Write(data)
	cipherStr := md5Ctx.Sum(nil)
	result := hex.EncodeToString(cipherStr)

	return strings.ToUpper(result)
}

/*
 * 根据结构体创建map的记录验证值
 * @param entity 参照结构体,仅用于取结构
 * @param data 数据
 * @return
 */
func CreateRecordKeyByMap(entity Entity, data map[string]interface{}) string {
	array := strings.Split(entity.BaseColumnNames(), ",") //关键就是按顺序进行

	temp := ""
	for _, k := range array { //只有数组才能固定顺序
		if k == "sRecordKey" { //sRecordKey字段不能参与,并且一旦轮询到sRecordKey就结束
			break
		}

		v, ok := data[k]
		if !ok {
			temp = temp + ";"
			continue
		}

		if v == nil {
			temp = temp + ";"
			continue
		}

		switch reflect.TypeOf(v).String() {
		case "time.Time":
			temp = temp + v.(time.Time).Format(timeFormat) + ";"
		default:
			temp = temp + fmt.Sprintf("%v", v) + ";"
		}
	}

	b := []byte(temp)
	md5Ctx := md5.New()
	md5Ctx.Write(b)
	cipherStr := md5Ctx.Sum(nil)
	result := hex.EncodeToString(cipherStr)

	return strings.ToUpper(result)
}

/**
 * 验证'记录验证串'是否正确
 * @param entity
 * @return
 */
func CheckRecordKey(entity Entity) bool {
	nowKey := CreateRecordKey(entity)

	v := reflect.ValueOf(entity)
	oldKey := v.FieldByName(TableRecordKeyName).Interface().(string)

	return oldKey == nowKey
}

/**
 * 设置当前实体的'记录验证串'值
 * @param entity
 * @return 返回新值
 */
func SetRecordKey(entity Entity) string {
	nowKey := CreateRecordKey(entity)

	v := reflect.ValueOf(entity).Elem()
	v.FieldByName(TableRecordKeyName).SetString(nowKey)

	return nowKey
}

// /* 相对鱼每个表中定义一个变量来保存数据库表名来说性能太差
//  * 结构体映射表名,处理结构体名称与表名不一致的情况
//  * @return
//  */
// func TableName(entity Entity) string {
// 	array := strings.Split(entity.BaseColumnNames(), ",")

// 	var dbName, tableName string
// 	var dataInfo *DataInfo
// 	for _, key := range array {
// 		dataInfo = entity.GetDataInfo(key)
// 		if dataInfo.Gbkey {
// 			dbName = dataInfo.GsDbName
// 			tableName = dataInfo.GsTableName
// 			break
// 		}
// 	}

// 	if dataInfo != nil && tableName == "" {
// 		dbName = dataInfo.GsDbName
// 		tableName = dataInfo.GsTableName
// 	}

// 	id := dbName + "." + tableName

// 	name := GetTableNameById(id)
// 	if name != "" {
// 		return name
// 	}

// 	if dbName == "" {
// 		return tableName
// 	}

// 	dbName = dbMap[dbName] //从注册数据库别名集合中获取到实际的库名
// 	if dbName == "" {
// 		return id //如果没有别名,则直接返回id
// 	}

// 	return dbName + tableName //别名中存在'.'
// }

/*
 * 结构体简略表名(无库名)
 * @return
 */
func SimpleTableName(entity Entity) string {
	return EntityTableName(entity)
}

/**
 * 取数据值
 * @param entity
 * @param name 字段名
 * @return
 */
func GetVal(entity Entity, name string) interface{} {
	// // 使用反射获取结构体类型和值
	// entityValue := reflect.ValueOf(entity).Elem() // 获取指针指向的值
	// entityType := entityValue.Type()

	// // 遍历结构体的所有字段
	// for i := 0; i < entityType.NumField(); i++ {
	// 	fieldType := entityType.Field(i)
	// 	fieldValue := entityValue.Field(i)

	// 	jsonTag := fieldType.Tag.Get("json") // 获取json标签

	// 	// 检查是否有特定的json标签
	// 	if jsonTag == name {
	// 		return fieldValue.Interface()
	// 	}
	// }

	// return nil

	pValue := reflect.ValueOf(entity)
	return getFieldVal(pValue, name)
}

/**
 * 设置数据值(此函数用于未知结构体的情况下调用)
 * @param name 字段名
 * @param val 值
 * @return
 */
func SetVal(entity Entity, name string, val interface{}) {
	pValue := reflect.ValueOf(entity)
	setFieldVal(pValue, name, val)
}

/**
 * 将map转成实体
 * data 数据
 * entity 数据结构
 */
func ToEntity(data map[string]interface{}, entity Entity) (Entity, int, error) {
	if data == nil {
		return nil, 1001, errors.New("map为nil")
	}

	if entity == nil {
		return nil, 1002, errors.New("数据结构为nil")
	}

	SetDefault(entity, true) //补齐默认值

	if !EntityHasRecordKey(entity) { //如果没有sRecordKey字段则直接结束
		MapSetEntity(data, entity) //Map设置结构体
		return entity, 1999, nil
	}

	MapSetEntity(data, entity) //Map设置结构体

	sRecordKey := CreateRecordKey(entity)
	SetVal(entity, TableRecordKeyName, sRecordKey)

	return entity, 1999, nil
}

// Map设置结构体
func MapSetEntity(data map[string]interface{}, entity Entity) Entity {
	pValue := reflect.ValueOf(entity) // 获取指针指向的值
	setFieldsVal(pValue, data, true)  //设置值

	return entity
}

// ----------- Map转结构体 开始 ----------- //

// 将map数据转换为实体
func MapToEntity(data map[string]interface{}, entity Entity) Entity {
	result := mapToEntity(data, entity) // mapToStruct 将map数据转换为指定的结构体实例

	return result.(Entity)
}

// mapToStruct 将map数据转换为指定的结构体实例
func mapToEntity(data map[string]interface{}, target interface{}) interface{} {
	targetValue := reflect.ValueOf(target)
	if targetValue.Kind() == reflect.Ptr { //传入的是指针如:&User{}
		//v = v.Elem() // 获取指针指向的值
	} else { //传入的是实体,如User{}
		// 获取目标结构体的类型
		targetType := reflect.TypeOf(target)
		targetPtrType := reflect.PtrTo(targetType)

		// 创建一个新的指针类型
		newTarget := reflect.New(targetPtrType.Elem()).Interface()

		// 将原始值复制到新指针中
		reflect.ValueOf(newTarget).Elem().Set(reflect.ValueOf(target))

		// 重新设置目标为指针类型
		target = newTarget
		targetValue = reflect.ValueOf(target)
	}

	v := targetValue.Elem() // 获取目标结构体的元素值

	for key, val := range data {
		setField(v, key, val)
	}

	if targetValue.Kind() == reflect.Ptr { //如果参数本身就是指针,则参数已经被修改,直接返回参数即可
		return target
	}

	result := v.Interface() //参数不是指针,属于内部结构体,需要返回指针

	return &result
}

// setField 遍历结构体并设置字段值，如果字段名与key相同，则设置为val
func setField(v reflect.Value, key string, val interface{}) {
	// 检查是否为结构体
	if v.Kind() != reflect.Struct {
		return
	}

	for i := 0; i < v.NumField(); i++ {
		field := v.Field(i)

		fieldType := v.Type().Field(i)

		// 获取字段的json标签
		jsonTag := fieldType.Tag.Get("json")
		if jsonTag == "" {
			continue
		}

		// 解析json标签
		parts := strings.Split(jsonTag, ",")
		if len(parts) > 0 && parts[0] == key {
			// 尝试将 val 转换为字段类型
			canSetValue(field, val)
			// if _, ok := canSetValue(field, val); ok { //有可能其它嵌套结构体也有同名字段
			// field.Set(reflect.ValueOf(cVal))
			// }
		}

		// 递归处理嵌套结构体或指针
		if field.Kind() == reflect.Ptr && !field.IsNil() {
			elem := field.Elem()
			if elem.Kind() == reflect.Struct {
				setField(elem, key, val)
			}

			continue
		}

		if field.Kind() == reflect.Struct {
			setField(field, key, val)
			continue
		}

		if field.Kind() == reflect.Interface { // 处理 interface{} 类型
			if field.IsNil() && (jsonTag == key) { // 如果类型为interface{}的字段当前值为nil,且json键值与map键值相符,则赋值,否则无法赋值
				field.Set(reflect.ValueOf(val))
				continue
			}

			handleInterface(field, key, val)
			continue
		}
	}
}

// handleInterface 处理 interface{} 类型的字段
func handleInterface(v reflect.Value, key string, val interface{}) {
	if v.IsNil() {
		return
	}

	elem := v.Elem() // 获取实际类型

	switch elem.Kind() {
	case reflect.Map:
		handleMap(elem, key, val) // 处理 map 类型
		return
	case reflect.Struct:
		setField(elem, key, val) // 处理结构体类型
		return
	}
}

// handleMap 处理 map 类型的字段
func handleMap(v reflect.Value, key string, val interface{}) {
	for _, k := range v.MapKeys() {
		val0 := v.MapIndex(k)
		if val0.Kind() == reflect.Struct {
			setField(val0, key, val)
		} else if val0.Kind() == reflect.Map {
			handleMap(val0, key, val)
		} else {
			// 尝试将 val 转换为字段类型
			if cVal, ok := canSetValue(val0, val); ok {
				val0.Set(reflect.ValueOf(cVal))
			}
		}
	}
}

// canSetValue 判断是否可以将 val 转换为字段类型
func canSetValue(field reflect.Value, val interface{}) (interface{}, bool) {
	fieldValue := reflect.ValueOf(val)
	fieldType := field.Type()

	switch fieldType.Kind() {
	case reflect.String:
		if fieldValue.Type().ConvertibleTo(fieldType) {
			field.Set(fieldValue.Convert(fieldType))
			return val, true
		}
	case reflect.Int, reflect.Int8, reflect.Int16, reflect.Int32, reflect.Int64:
		if fieldValue.Type().ConvertibleTo(fieldType) {
			field.Set(fieldValue.Convert(fieldType))
			return val, true
		}
	case reflect.Float32, reflect.Float64:
		if fieldValue.Type().ConvertibleTo(fieldType) {
			field.Set(fieldValue.Convert(fieldType))
			return val, true
		}
	case reflect.Bool:
		if fieldValue.Type().ConvertibleTo(fieldType) {
			field.Set(fieldValue.Convert(fieldType))
			return val, true
		}

		temp := strings.ToUpper(fmt.Sprintf("%v", fieldValue))
		bl := (temp == "1") || (temp == "TRUE")
		field.Set(reflect.ValueOf(bl))
		return bl, bl
	case reflect.Struct:
		switch fieldType.String() {
		case "time.Time":
			if fieldValue.Type().Kind() == reflect.String {
				t := toDate(fieldValue.String())
				field.Set(reflect.ValueOf(t))
				return t, true
			}

			field.Set(fieldValue)
			return val, true
		case "decimal.Decimal":
			t, err := decimal.NewFromString(fmt.Sprintf("%v", fieldValue))
			if err != nil {
				field.Set(reflect.ValueOf(decimal.Zero))
				return decimal.Zero, true
			}
			field.Set(reflect.ValueOf(t))
			return t, true
		}
	}

	return val, false
}

// 字符串转时间
func toDate(str string) time.Time {
	str = strings.TrimSpace(str)
	if str == "" {
		return time.Now()
	}

	str = strings.Replace(str, "/", "-", -1)
	str = strings.Replace(str, "T", " ", -1)
	str = strings.Replace(str, "Z", "", -1)
	str = strings.Replace(str, "z", "", -1)

	iEd := strings.LastIndex(str, ".")
	if iEd > -1 {
		str = str[:iEd]
	}

	local, _ := time.LoadLocation("Asia/Shanghai")
	if len(str) == 19 {
		result, _ := time.ParseInLocation(timeFormat, str, local)
		return result
	}

	if len(str) == 16 {
		result, _ := time.ParseInLocation("2006-01-02 15:04", str, local)
		return result
	}

	result, _ := time.ParseInLocation("2006-01-02", str, local)

	return result
}

// ----------- Map转结构体 结束 ----------- //

// ----------- 结构体转Map 开始 ----------- //

// 将结构体的所有属性及其值存入 map[string]interface{}
func ToMap(entity interface{}) map[string]interface{} {
	return structToMap(entity)
}

// 将结构体的所有属性及其值存入 map[string]interface{}
func structToMap(source interface{}) map[string]interface{} {
	entityValue := reflect.ValueOf(source)

	if entityValue.Kind() == reflect.Ptr { //传入的是指针如:&User{}
		entityValue = entityValue.Elem() // 获取指针指向的值
	}

	entityType := entityValue.Type()

	result := make(map[string]interface{})

	// 遍历结构体的所有字段
	for i := 0; i < entityType.NumField(); i++ {
		fieldType := entityType.Field(i)
		fieldValue := entityValue.Field(i)

		jsonTag := fieldType.Tag.Get("json")

		// 跳过忽略字段
		if jsonTag == "-" {
			continue
		}

		// 获取当前字段的键名
		key := jsonTag

		// 处理匿名结构体
		if fieldType.Anonymous {
			if fieldValue.Kind() == reflect.Struct {
				subMap := structToMap(fieldValue.Interface()) //递归
				for k, v := range subMap {
					//result["@@@Anonymous_" + k] = v//如果发现匿名字段覆盖了上级字段,则必须进行特殊处理,在此保留代码
					result[k] = v
				}
			}

			continue
		}

		if fieldValue.Kind() == reflect.Ptr && !fieldValue.IsNil() {
			// 处理结构体指针
			subMap := structToMap(fieldValue.Elem().Interface()) //递归
			result[key] = subMap
			continue
		}

		// 直接处理普通字段
		if fieldType.Type == reflect.TypeOf(time.Time{}) {
			// 格式化 time.Time 类型
			if fieldValue.CanInterface() {
				t := fieldValue.Interface().(time.Time)
				result[key] = t.Format(timeFormat)
			}
			continue
		}

		result[key] = fieldValue.Interface()
	}

	return result
}

// ----------- 结构体转Map 结束 ----------- //

// ----------- 特殊字段是否存在判断 开始 ----------- //

func EntityAutoKey(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")

	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GbExtra && dataInfo.Gbkey {
			return true
		}
	}

	return false
}

func EntityHasPid(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TablePidKey {
			return true
		}
	}

	return false
}
func EntityHasPath(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TablePathKey {
			return true
		}
	}

	return false
}
func EntityHasRecordKey(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableRecordKeyName {
			return true
		}
	}

	return false
}
func EntityHasMemo(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TablesMemo {
			return true
		}
	}

	return false
}
func EntityHasCreator(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableCreatorName {
			return true
		}
	}

	return false
}
func EntityHasCreateDate(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableCreateDateName {
			return true
		}
	}

	return false
}
func EntityHasModifieder(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableModifiederName {
			return true
		}
	}

	return false
}
func EntityHasModifiedDate(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableModifiedDateName {
			return true
		}
	}

	return false
}
func EntityHasState(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableStateName {
			return true
		}
	}

	return false
}
func EntityHasIndex(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableIndexName {
			return true
		}
	}

	return false
}
func EntityHasVersion(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableVersionName {
			return true
		}
	}

	return false
}
func EntityHasPassword(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TablePasswordName {
			return true
		}
	}

	return false
}
func EntityHasSign(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TablesSign {
			return true
		}
	}

	return false
}
func EntityHasOnlyign(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableOnlyignName {
			return true
		}
	}

	return false
}
func EntityHasDelSign(entity Entity) bool {
	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		if dataInfo.GsName == TableDelSignName {
			return true
		}
	}

	return false
}

// ----------- 特殊字段是否存在判断 结束 ----------- //

/**
 * 结构体映射表简化信息
 */
func GetTableInfo(entity Entity) *TableInfo {
	result := &TableInfo{}

	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		dataInfo := entity.GetDataInfo(key)
		result.GsDbName = dataInfo.GsDbName
		result.GsTableName = dataInfo.GsTableName

		if dataInfo.Gbkey && result.GsKeyName == "" {
			result.GsKeyName = dataInfo.GsName
			result.GbAutoKey = dataInfo.GbExtra
			result.GiKeyLen = dataInfo.GiMaxLength
			continue
		}

		if dataInfo.GbBigTxt {
			result.GsBigTextFields += dataInfo.GsName + ";"
		}

		switch dataInfo.GsName {
		case TablePidKey:
			result.GbHasPid = true
		case TablePathKey:
			result.GbHasPath = true
		case TableRecordKeyName:
			result.GbHasRecordKey = true
		case TablesMemo:
			result.GbHasMemo = true
		case TableCreatorName:
			result.GbHasCreator = true
		case TableCreateDateName:
			result.GbHasCreateDate = true
		case TableModifiederName:
			result.GbHasModifieder = true
		case TableModifiedDateName:
			result.GbHasModifiedDate = true
		case TableStateName:
			result.GbHasState = true
		case TableIndexName:
			result.GbHasIndex = true
		case TableVersionName:
			result.GbHasVersion = true
		case TablePasswordName:
			result.GbHasPassword = true
		case TablesSign:
			result.GbHasSign = true
		case TableOnlyignName:
			result.GbHasOnlyign = true
		case TableDelSignName:
			result.GbHasDelSign = true
		}
	}

	return result
}

// ----------- 实体验证 开始 ----------- //

/**
 * 对对象中添加了DataInfo注解的不为null的属性检查限制
 * data 数据
 * entity 检查用数据结构
 * ignoreNames 待忽略的字段
 */
func ValidAttr(data map[string]interface{}, entity Entity, ignoreNames []string) (int, error) {
	if data == nil {
		return 1001, createError("数据为nil")
	}

	if entity == nil {
		return 1002, createError("数据结构为nil")
	}

	ignoreNamesMap := make(map[string]struct{}, len(ignoreNames))
	for _, v := range ignoreNames {
		ignoreNamesMap[v] = struct{}{}
	}

	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		if _, ok := ignoreNamesMap[key]; ok { //忽略字段
			continue
		}

		dataInfo := entity.GetDataInfo(key)
		if dataInfo == nil { //这个字段没有数据信息(一般不太可能)
			return 1003, createError("发现不符合框架规则的字段:", key)
		}

		if !dataInfo.GbNull { //字段是否允许为空
			temp := data[key]
			if temp == nil { //数据如果为空
				return 1004, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]不允许为空！")
			} else if fmt.Sprintf("%v", temp) == "" {
				return 1005, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]不允许为空！")
			}
		}

		oldValue := fmt.Sprintf("%v", data[key])
		strType := dataInfo.GsDbFileType

		if strType == "int" { // 此时oldValue的值为:"<int Value>"
			oldValue = fmt.Sprintf("%v", data[key])
		}

		iL := dataInfo.GiMaxLength //真正存储字段的最大长度要求不可能小于1,否则无意义,如果定义iMaxLength为0,或-1则说明是要忽略检查的
		if !strings.Contains("/datetime/date/time/", strType) && iL > 0 && iL < utf8.RuneCountInString(oldValue) {
			return 1006, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]长度超出，最大长度限制为:", iL)
		}
	}

	return 1999, nil
}

/**
 * 对'编辑'对象中添加了DataInfo注解的不为null的属性检查限制
 * data 数据
 * entity 检查用数据结构
 * ignoreNames 待忽略的字段
 */
func ValidAttrByEdit(data map[string]interface{}, entity Entity, ignoreNames []string) (int, error) {
	if data == nil {
		return 1001, errors.New("数据为nil")
	}

	if entity == nil {
		return 1002, errors.New("数据结构为nil")
	}

	ignoreNamesMap := make(map[string]string, len(ignoreNames))
	for _, v := range ignoreNames {
		ignoreNamesMap[v] = v
	}

	allDataInfo := AllDataInfo(entity)
	for _, dataInfo := range allDataInfo {
		value, ok := data[dataInfo.GsName]
		if !ok {
			continue //此字段不参与更新则不进行检查
		}

		if _, ok = ignoreNamesMap[dataInfo.GsName]; ok {
			continue
		}

		oldValue := strings.TrimSpace(fmt.Sprintf("%v", value))
		strType := dataInfo.GsDbFileType

		if strType == "int" { // 此时oldValue的值为:"<int Value>"
			oldValue = fmt.Sprintf("%v", value)
		}

		iL := dataInfo.GiMaxLength //真正存储字段的最大长度要求不可能小于1,否则无意义,如果定义iMaxLength为0,或-1则说明是要忽略检查的
		if (!strings.Contains("/datetime/date/time/time.Time/decimal.Decimal", strType)) && (iL > 0) && (iL < utf8.RuneCountInString(oldValue)) {
			return 1003, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]长度超出，最大长度限制为:", iL)
		}

		if !dataInfo.GbNull && (oldValue == "<nil>" || oldValue == "") {
			return 1004, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]不允许为空！")
		}

		if strings.Contains("/decimal.Decimal/*big.Float", strType) && (iL > 0) {
			str := fmt.Sprintf("%v", data[dataInfo.GsName])
			array := strings.Split(str, ".")

			if dataInfo.GiIntegralLength < len(array[0]) {
				return 1005, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]整数超出，最大长度限制为:", dataInfo.GiIntegralLength)
			}

			if (len(array) > 1) && (dataInfo.GiDecimalLength < len(array[1])) {
				return 1006, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]小数超过，最大长度限制为:", dataInfo.GiIntegralLength)
			}
		}

		if strings.Contains("/float64/float32/", strType) && (iL > 0) {
			str := fmt.Sprintf("%f", data[dataInfo.GsName])
			array := strings.Split(str, ".")

			if dataInfo.GiIntegralLength < len(array[0]) {
				return 1005, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]整数超出，最大长度限制为:", dataInfo.GiIntegralLength)
			}

			if (len(array) > 1) && (dataInfo.GiDecimalLength < len(array[1])) {
				return 1006, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]小数超过，最大长度限制为:", dataInfo.GiIntegralLength)
			}
		}
	}

	return 1999, nil
}

/**
 * 对'新增'对象中添加了DataInfo注解的属性检查限制
 * entity 检查用数据结构
 * ignoreNames 待忽略的字段
 */
func ValidAttrByAdd(entity Entity, ignoreNames []string) (int, error) {
	if entity == nil {
		return 1001, createError("数据结构为nil")
	}

	ignoreNamesMap := make(map[string]struct{}, len(ignoreNames))
	for _, v := range ignoreNames {
		ignoreNamesMap[v] = struct{}{}
	}

	pType := reflect.TypeOf(entity).Elem()   // 获取指针指向的类型
	pValue := reflect.ValueOf(entity).Elem() // 获取指针指向的值

	for i := 0; i < pValue.NumField(); i++ {
		field := pValue.Field(i)
		jsonTag := pType.Field(i).Tag.Get("json") // 获取json标签

		if jsonTag == "-" {
			continue
		}

		dataInfo := GetDataInfo(entity, jsonTag)
		if dataInfo == nil {
			continue
		}

		if _, ok := ignoreNamesMap[dataInfo.GsName]; ok { //排除忽略字段
			continue
		}

		oldValue := fmt.Sprintf("%v", reflect.ValueOf(field))
		strType := fmt.Sprintf("%v", field.Type()) //类型

		if strType == "int" { // 此时oldValue的值为:"<int Value>"
			oldValue = fmt.Sprintf("%v", field)
		}

		iL := dataInfo.GiMaxLength //真正存储字段的最大长度要求不可能小于1,否则无意义,如果定义iMaxLength为0,或-1则说明是要忽略检查的
		if !strings.Contains("/datetime/date/time/time.Time/decimal.Decimal/", strType) && iL > 0 && iL < utf8.RuneCountInString(oldValue) {
			return 1002, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]长度超出，最大长度限制为:", iL)
		}

		if !dataInfo.GbNull && ((oldValue == "<nil>") || (oldValue == "")) {
			return 1003, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]不允许为空！")
		}

		if strings.Contains("/datetime/date/time/time.Time/", strType) && !dataInfo.GbNull && (oldValue == "" || oldValue == "0001-01-01 00:00:00 +0000 UTC" || oldValue == "<nil>") {
			return 1004, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]不允许为空！")
		}

		if strings.Contains("/decimal.Decimal/*big.Float", strType) && (iL > 0) {
			str := fmt.Sprintf("%v", field)
			array := strings.Split(str, ".")

			if dataInfo.GiIntegralLength < len(array[0]) {
				return 1005, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]整数超出，最大长度限制为:", dataInfo.GiIntegralLength)
			}

			if (len(array) > 1) && (dataInfo.GiDecimalLength < len(array[1])) {
				return 1006, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]小数超过，最大长度限制为:", dataInfo.GiIntegralLength)
			}
		}

		if strings.Contains("/float64/float32/", strType) && (iL > 0) {
			str := fmt.Sprintf("%v", field)
			array := strings.Split(str, ".")

			if dataInfo.GiIntegralLength < len(array[0]) {
				return 1005, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]整数超出，最大长度限制为:", dataInfo.GiIntegralLength)
			}

			if (len(array) > 1) && (dataInfo.GiDecimalLength < len(array[1])) {
				return 1006, createError(dataInfo.GsComment, "[", dataInfo.GsName, "]小数超过，最大长度限制为:", dataInfo.GiIntegralLength)
			}
		}
	}

	return 1999, nil
}

/**
 * 按实体保留map中的数据
 * object 待检查对象
 * data 数据
 * fieldPrefix 字段前缀(可不传)
 */
func HoldByEntity(entity Entity, data map[string]interface{}) map[string]interface{} {
	result := make(map[string]interface{})

	if entity == nil {
		return result
	}

	if data == nil {
		return result
	}

	array := strings.Split(entity.BaseColumnNames(), ",")
	for _, key := range array {
		if v, ok := data[key]; ok {
			result[key] = v
		}
	}

	return result
}

/**
 * 创建错误信息
 * msg 错误信息
 * 返回错误信息
 */
func createError(msg ...interface{}) error {
	var build strings.Builder
	for _, v := range msg {
		build.WriteString(fmt.Sprintf("%v", v))
	}

	return errors.New(build.String())
}

// ----------- 实体验证 结束 ----------- //

// ----------- 反射属性操作 开始 ----------- //

// 递归访问所有字段
func getFieldsVal(val reflect.Value) map[string]interface{} {
	result := make(map[string]interface{})

	var t reflect.Type
	if val.Kind() == reflect.Ptr { // 判断是否是指针类型
		val = val.Elem()
		t = val.Type()
	} else {
		t = val.Type()
	}

	// 遍历结构体字段,遍历优先级: 具名结构体>匿名结构体>字段; 按此遍历将实现后面遍历到的同名字段将覆盖前面被遍历到的

	// 处理具名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if !field.Anonymous && field.Type.Kind() == reflect.Struct {
			anonVal := val.Field(i)
			if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
				anonVal = anonVal.Elem()
			}

			temp := getFieldsVal(anonVal)
			for k, v := range temp {
				result[k] = v
			}
		}
	}

	// 处理匿名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Anonymous && field.Type.Kind() == reflect.Struct {
			anonVal := val.Field(i)
			if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
				anonVal = anonVal.Elem()
			}

			temp := getFieldsVal(anonVal)
			for k, v := range temp {
				result[k] = v
			}
		}
	}

	// 处理最外层普通属性
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		jsonTag := field.Tag.Get("json")
		if jsonTag != "" {
			fieldValue := val.Field(i).Interface()
			result[jsonTag] = fieldValue
		}
	}

	return result
}

// 取指定字段值,从外往内找,找到就结束
func getFieldVal(val reflect.Value, jsonName string) interface{} {
	var t reflect.Type
	if val.Kind() == reflect.Ptr { // 判断是否是指针类型
		val = val.Elem()
		t = val.Type()
	} else {
		t = val.Type()
	}

	//在外层找,再向内层(匿名结构体)查找

	// 最外层普通属性
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		jsonTag := field.Tag.Get("json")
		if jsonTag == jsonName {
			fieldValue := val.Field(i).Interface()
			return fieldValue
		}
	}

	// 处理匿名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if !field.Anonymous {
			continue
		}

		if field.Type.Kind() != reflect.Struct {
			continue
		}

		anonVal := val.Field(i)
		if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
			anonVal = anonVal.Elem()
		}

		temp := getFieldVal(anonVal, jsonName)
		if temp != nil {
			return temp
		}
	}

	// 处理具名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Anonymous || field.Type.Kind() != reflect.Struct {
			continue
		}

		anonVal := val.Field(i)
		if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
			anonVal = anonVal.Elem()
		}

		temp := getFieldVal(anonVal, jsonName)
		if temp != nil {
			return temp
		}
	}

	return nil
}

// 设置指定字段的值,从外往内找,找到就结束
func setFieldVal(val reflect.Value, jsonName string, data interface{}) bool {
	var t reflect.Type
	if val.Kind() == reflect.Ptr { // 判断是否是指针类型
		val = val.Elem()
		t = val.Type()
	} else {
		t = val.Type()
	}

	//在外层找,再向内层(匿名结构体)查找

	// 最外层普通属性
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		jsonTag := field.Tag.Get("json")
		if jsonTag == jsonName {
			fieldV := val.Field(i)
			canSetValue(fieldV, data)
			// if _, ok := canSetValue(fieldV, data); ok { //有可能其它嵌套结构体也有同名字段
			//fieldV.Set(reflect.ValueOf(cData))
			// }
			return true
		}
	}

	// 处理匿名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if !field.Anonymous {
			continue
		}

		if field.Type.Kind() != reflect.Struct {
			continue
		}

		anonVal := val.Field(i)
		if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
			anonVal = anonVal.Elem()
		}

		if setFieldVal(anonVal, jsonName, data) {
			return true
		}
	}

	// 处理具名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Anonymous || field.Type.Kind() != reflect.Struct {
			continue
		}

		anonVal := val.Field(i)
		if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
			anonVal = anonVal.Elem()
		}

		if setFieldVal(anonVal, jsonName, data) {
			return true
		}
	}

	return false
}

// 按map设置指定字段的值,从外往内找,找到就结束
func setFieldsVal(val reflect.Value, data map[string]interface{}, cover bool) {
	var t reflect.Type
	if val.Kind() == reflect.Ptr { // 判断是否是指针类型
		val = val.Elem()
		t = val.Type()
	} else {
		t = val.Type()
	}

	//在外层找,再向内层(匿名结构体)查找

	// 最外层普通属性
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)
		jsonTag := field.Tag.Get("json")
		if v, ok := data[jsonTag]; ok {
			fieldV := val.Field(i)

			oldValue := reflect.ValueOf(field)
			if (fmt.Sprintf("%v", oldValue) != "") && !cover {
				continue //如果值不为空,且不允许覆盖,则不要赋值
			}

			canSetValue(fieldV, v)
			//fieldV.Set(reflect.ValueOf(v))
		}
	}

	// 处理匿名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if !field.Anonymous {
			continue
		}

		if field.Type.Kind() != reflect.Struct {
			continue
		}

		anonVal := val.Field(i)
		if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
			anonVal = anonVal.Elem()
		}

		setFieldsVal(anonVal, data, cover)
	}

	// 处理具名结构体
	for i := 0; i < t.NumField(); i++ {
		field := t.Field(i)

		if field.Anonymous || field.Type.Kind() != reflect.Struct {
			continue
		}

		anonVal := val.Field(i)
		if anonVal.Kind() == reflect.Ptr && !anonVal.IsNil() {
			anonVal = anonVal.Elem()
		}

		setFieldsVal(anonVal, data, cover)
	}
}

// ----------- 反射属性操作 结束 ----------- //

// ----------- 数据库字段名常量 开始 ----------- //

// 初始化数据库字段名常量
func initTableKeyName() {
	root := ""
	exePath, err := os.Executable()
	if err != nil {
		root = "."
	}

	root, _ = filepath.EvalSymlinks(filepath.Dir(exePath))

	filePath := root + "/config/entity.ini"

	// 尝试加载配置文件
	cfg, err := ini.Load(filePath)
	if err != nil {
		// 文件不存在或打开失败，返回默认值
		initTableKeyNameDefalut() //配置文件不存在,取默认
		return
	}

	// 获取 "mode" 部分
	modeSection, err := cfg.GetSection("mode")
	if err != nil {
		// "mode" 部分不存在，返回默认值
		initTableKeyNameDefalut() //配置文件不存在,取默认
		return
	}

	// 获取 "type" 键的值
	modeType, err := modeSection.GetKey("type")
	if err != nil {
		// "type" 键不存在，返回默认值
		initTableKeyNameDefalut() //配置文件不存在,取默认
		return
	}

	sType := strings.ToLower(modeType.String())
	if sType == "default" {
		initTableKeyNameDefalut() //取默认方式
	} else if sType == "popular" {
		initTableKeyNamePopular() //取通俗方式
	} else if sType == "custom" {
		customSection, err := cfg.GetSection("custom")
		if err != nil {
			// "mode" 部分不存在，返回默认值
			initTableKeyNameDefalut() //自定义配置不存在,取默认
			return
		}

		initTableKeyNameCustom(customSection) //取自定义方式
	} else {
		initTableKeyNameDefalut() //取默认方式
	}
}

// 初始化数据库字段名常量-默认值方式
func initTableKeyNameDefalut() {
	tableKeyNameMap = map[string]string{
		"BaseSystem":    "BaseSystem",    //基本数据库库名
		"sId":           "sId",           //数据库表主键名称(字符串形式)
		"iId":           "iId",           //数据库表主键名称(自增长形式)
		"uId":           "uId",           //数据库表主键名称(UUID形式)
		"sPid":          "sPid",          //数据库表字段名称-上级字段名
		"sPath":         "sPath",         //数据库表字段名称-主键路径名
		"sName":         "sName",         //数据库表字段名称-树形节点名
		"sCreator":      "sCreator",      //数据库表字段名称-创建人
		"dCreateDate":   "dCreateDate",   //数据库表字段名称-创建时间
		"sModifieder":   "sModifieder",   //数据库表字段名称-修改人
		"dModifiedDate": "dModifiedDate", //数据库表字段名称-修改时间
		"iState":        "iState",        //数据库表字段名称-状态值
		"iIndex":        "iIndex",        //数据库表字段名称-排序值
		"iVersion":      "iVersion",      //数据库表字段名称-版本号
		"sPassword":     "sPassword",     //数据库表字段名称-密码
		"iDelSign":      "iDelSign",      //数据库表字段名称-逻辑删除标识
		"iSetp":         "iSetp",         //数据库表字段名称-步骤值
		"sOnlyign":      "sOnlyign",      //数据库表字段名称-唯一标识
		"Dictionary":    "Dictionary",    //字典表表名
		"sValue":        "sValue",        //字典表值字段名
		"sRecordKey":    "sRecordKey",    //记录验证串字段名
		"sSign":         "sSign",         //标识字段名
		"sMemo":         "sMemo",         //备注字段名
	}

	initTableKeyNameValue()
}

// 初始化数据库字段名常量-通俗方式
func initTableKeyNamePopular() {
	tableKeyNameMap = map[string]string{
		"BaseSystem":    "base_system",   //基本数据库库名
		"sId":           "id",            //数据库表主键名称(字符串形式)
		"iId":           "id",            //数据库表主键名称(自增长形式)
		"uId":           "uId",           //数据库表主键名称(UUID形式)
		"sPid":          "pid",           //数据库表字段名称-上级字段名
		"sPath":         "path",          //数据库表字段名称-主键路径名
		"sName":         "name",          //数据库表字段名称-树形节点名
		"sCreator":      "creator",       //数据库表字段名称-创建人
		"dCreateDate":   "create_date",   //数据库表字段名称-创建时间
		"sModifieder":   "modifieder",    //数据库表字段名称-修改人
		"dModifiedDate": "modified_date", //数据库表字段名称-修改时间
		"iState":        "state",         //数据库表字段名称-状态值
		"iIndex":        "index",         //数据库表字段名称-排序值
		"iVersion":      "version",       //数据库表字段名称-版本号
		"sPassword":     "password",      //数据库表字段名称-密码
		"iDelSign":      "del_sign",      //数据库表字段名称-逻辑删除标识
		"iSetp":         "setp",          //数据库表字段名称-步骤值
		"sOnlyign":      "onlyign",       //数据库表字段名称-唯一标识
		"Dictionary":    "dictionary",    //字典表表名
		"sValue":        "value",         //字典表值字段名
		"sRecordKey":    "record_key",    //记录验证串字段名
		"sSign":         "sign",          //标识字段名
		"sMemo":         "memo",          //备注字段名
	}

	initTableKeyNameValue()
}

// 初始化数据库字段名常量-自定义方式
func initTableKeyNameCustom(section *ini.Section) {
	for _, key := range section.Keys() {
		tableKeyNameMap[key.Name()] = key.String()
	}

	initTableKeyNameValue()
}

func initTableKeyNameValue() {
	BaseSystemName = tableKeyNameMap["BaseSystem"]           //基本数据库库名
	TableMajorKeyString = tableKeyNameMap["sId"]             //数据库表主键名称(字符串形式)
	TableMajorKeyAutoInt = tableKeyNameMap["iId"]            //数据库表主键名称(自增长形式)
	TableMajorKeyUuId = tableKeyNameMap["uId"]               //数据库表主键名称(UUID形式)
	TablePidKey = tableKeyNameMap["sPid"]                    //数据库表字段名称-上级字段名
	TablePathKey = tableKeyNameMap["sPath"]                  //数据库表字段名称-主键路径名
	TableTreeNodeName = tableKeyNameMap["sName"]             //数据库表字段名称-树形节点名
	TableCreatorName = tableKeyNameMap["sCreator"]           //数据库表字段名称-创建人
	TableCreateDateName = tableKeyNameMap["dCreateDate"]     //数据库表字段名称-创建时间
	TableModifiederName = tableKeyNameMap["sModifieder"]     //数据库表字段名称-修改人
	TableModifiedDateName = tableKeyNameMap["dModifiedDate"] //数据库表字段名称-修改时间
	TableStateName = tableKeyNameMap["iState"]               //数据库表字段名称-状态值
	TableIndexName = tableKeyNameMap["iIndex"]               //数据库表字段名称-排序值
	TableVersionName = tableKeyNameMap["iVersion"]           //数据库表字段名称-版本号
	TablePasswordName = tableKeyNameMap["sPassword"]         //数据库表字段名称-密码
	TableDelSignName = tableKeyNameMap["iDelSign"]           //数据库表字段名称-逻辑删除标识
	TableSetpName = tableKeyNameMap["iSetp"]                 //数据库表字段名称-步骤值
	TableOnlyignName = tableKeyNameMap["sOnlyign"]           //数据库表字段名称-唯一标识
	TableNameDictionary = tableKeyNameMap["Dictionary"]      //字典表表名
	TableDictionaryValueName = tableKeyNameMap["sValue"]     //字典表值字段名
	TableRecordKeyName = tableKeyNameMap["sRecordKey"]       //记录验证串字段名
	TablesSign = tableKeyNameMap["sSign"]                    //标识字段名
	TablesMemo = tableKeyNameMap["sMemo"]                    //备注字段名

	TableTreeRootValue = "00" //数据库树型表根节点默认值

	//------------------------------------------- //
	// GtableMajorKeyString      = "G" + tableKeyNameMap["sId"]           //属性对应数据库表主键名称(字符串形式)
	// GtableMajorKeyAutoInt     = "G" + tableKeyNameMap["iId"]           //属性对应数据库表主键名称(自增长形式)
	// GtableMajorKeyUuId        = "G" + tableKeyNameMap["uId"]           //属性对应数据库表主键名称(UUID形式)
	// GtablePidKey              = "G" + tableKeyNameMap["sPid"]          //属性对应数据库表字段名称-上级字段名
	// GtablePathKey             = "G" + tableKeyNameMap["sPath"]         //属性对应数据库表字段名称-主键路径名
	// GtableTreeNodeName        = "G" + tableKeyNameMap["sName"]         //属性对应数据库表字段名称-树形节点名
	// GtableCreatorName         = "G" + tableKeyNameMap["sCreator"]      //属性对应数据库表字段名称-创建人
	// GtableCreateDateName      = "G" + tableKeyNameMap["dCreateDate"]   //属性对应数据库表字段名称-创建时间
	// GtableModifiederName      = "G" + tableKeyNameMap["sModifieder"]   //属性对应数据库表字段名称-修改人
	// GtableModifiedDateName    = "G" + tableKeyNameMap["dModifiedDate"] //属性对应数据库表字段名称-修改时间
	// GtableStateName           = "G" + tableKeyNameMap["iState"]        //属性对应数据库表字段名称-状态值
	// GtableIndexName           = "G" + tableKeyNameMap["iIndex"]        //属性对应数据库表字段名称-排序值
	// GtableVersionName         = "G" + tableKeyNameMap["iVersion"]      //属性对应数据库表字段名称-版本号
	// GtablePasswordName        = "G" + tableKeyNameMap["sPassword"]     //属性对应数据库表字段名称-密码
	// GtableDelSignName         = "G" + tableKeyNameMap["iDelSign"]      //属性对应数据库表字段名称-逻辑删除标识
	// GtableSetpName            = "G" + tableKeyNameMap["iSetp"]         //属性对应数据库表字段名称-步骤值
	// GtableOnlyignName         = "G" + tableKeyNameMap["sOnlyign"]      //属性对应数据库表字段名称-唯一标识
	// GtableNameDictionary      = "G" + tableKeyNameMap["Dictionary"]    //属性对应字典表表名
	// GtableDictionaryValueName = "G" + tableKeyNameMap["sValue"]        //属性对应字典表值字段名
	// GtableRecordKeyName       = "G" + tableKeyNameMap["sRecordKey"]    //属性对应记录验证串字段名
	// GtablesSign               = "G" + tableKeyNameMap["sSign"]         //属性对应标识字段名
	// GtablesMemo               = "G" + tableKeyNameMap["sMemo"]         //属性对应备注字段名
	// GBaseSystemName           = "G" + tableKeyNameMap["BaseSystem"]    //属性对应基本数据库库名
	// GGtableTreeRootValue      = "00"                                   //属性对应数据库树型表根节点默认值
}

// ----------- 数据库字段名常量 结束 ----------- //
